from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
    QMessageBox, QWidget, QVBoxLayout, QHBoxLayout,
    QFrame, QTextEdit, QLabel, QLineEdit, QComboBox, QPushButton, QFormLayout, QGroupBox
)

from constants import *
from taskmanager import SerialManager

class SingleMotorControl(QWidget):
    def __init__(self):
        super().__init__()
        self.serial_motor_control = SerialManager()
        self.current_motor_index = 0
        self.initUI()
    
    def initUI(self):
        main_layout = QHBoxLayout()

        ## --------------- 1. 左侧: 串口连接 + 参数设置 ---------------
        left_layout = QVBoxLayout()
        
        # 串口选择 + 波特率配置
        com_group = QGroupBox("串口参数设置")
        com_layout = QFormLayout()
        self.serial_port_combo = QComboBox()
        self.serial_port_combo.addItems(self.serial_motor_control.get_available_ports())
        com_layout.addRow("Serial Port", self.serial_port_combo)
        self.baudrate_combo = QComboBox()
        self.baudrate_combo.addItems(["9600", "115200"])
        com_layout.addRow("Baudrate", self.baudrate_combo)
        com_group.setLayout(com_layout)
        left_layout.addWidget(com_group)
        
        # 串口按钮
        com_btn_layout = QHBoxLayout()
        self.refresh_button = QPushButton("Refresh")
        self.refresh_button.clicked.connect(self.on_refresh_button_clicked)
        self.connect_button = QPushButton("Connect")
        self.connect_button.clicked.connect(self.on_connect_button_clicked)
        com_btn_layout.addWidget(self.refresh_button)
        com_btn_layout.addWidget(self.connect_button)
        left_layout.addLayout(com_btn_layout)
        
        # MCU引脚配置
        pin_group = QGroupBox("MCU引脚配置")
        pin_layout = QFormLayout()
        motor_index = QComboBox()
        self.linEdit_pin_dir = QLabel()
        self.lineEdit_pin_pul = QLabel()
        self.lineEdit_pin_en = QLabel()
        motor_index.addItems([f"Motor {i}" for i in range(motor_num)])
        self.on_motor_index_changed(self.current_motor_index)
        motor_index.currentIndexChanged.connect(self.on_motor_index_changed)
        pin_layout.addRow("Motor index", motor_index)
        pin_layout.addRow("DIR Pin", self.linEdit_pin_dir)
        pin_layout.addRow("PULSE Pin", self.lineEdit_pin_pul)
        pin_layout.addRow("EN Pin", self.lineEdit_pin_en)
        pin_group.setLayout(pin_layout)
        left_layout.addWidget(pin_group)
        
        # 状态栏
        self.status_textEdit = QTextEdit("Disconnected")
        self.status_textEdit.setReadOnly(True)
        self.status_textEdit.setFrameShape(QFrame.NoFrame)
        self.status_textEdit.setLineWrapMode(QTextEdit.WidgetWidth)  # 自动换行
        self.status_textEdit.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)  # 显示垂直滚动条
        
        left_layout.addWidget(self.status_textEdit)
        # left_layout.setStretchFactor(self.status_textEdit, 1)  # 让 status_textEdit 占据剩余空间
        
        ## --------------- 2. 右侧: 电机控制 ---------------
        right_layout = QVBoxLayout()
        
        # 电机状态显示
        self.motor_status_label = QLabel("Motor Status: Disconnected")
        right_layout.addWidget(self.motor_status_label)
        
        # 驱动参数
        motor_param_group = QGroupBox("电机驱动参数")
        motor_param_layout = QFormLayout()
        self.motor_angle = QComboBox()
        self.motor_angle.addItems(["1.8°", "0.9°"])
        self.motor_angle.setCurrentIndex(0)
        motor_param_layout.addRow("步距角", self.motor_angle)
        
        self.mstep = QComboBox()
        self.mstep.addItems(["400", "800", "1600", "3200", "6400", "12800", "25600", "1000", "2000", "4000", "5000", "8000", "10000", "20000", "25000"])
        self.mstep.setCurrentIndex(0)
        motor_param_layout.addRow("细分 (Pulse/Rev)", self.mstep)
        
        motor_param_group.setLayout(motor_param_layout)
        right_layout.addWidget(motor_param_group)
        
        # 脉冲模式
        mode_pulse_group = QGroupBox("脉冲模式")
        mode_pulse_layout = QHBoxLayout()
        mode_pulse_layout.addWidget(QLabel("脉冲数"))
        self.pulse_number = 1000
        lineEdit_pulse_number = QLineEdit(str(self.pulse_number))
        lineEdit_pulse_number.textChanged.connect(self.on_pulse_number_changed)
        mode_pulse_layout.addWidget(lineEdit_pulse_number)
        
        mode_pulse_layout.addWidget(QLabel("脉冲周期（us/step）"))
        self.pulse_period = 1000
        lineEdit_pulse_period = QLineEdit(str(self.pulse_period))
        lineEdit_pulse_period.textChanged.connect(self.on_pulse_period_changed)
        mode_pulse_layout.addWidget(lineEdit_pulse_period)
        
        mode_pulse_button = QPushButton("Send")
        mode_pulse_button.clicked.connect(self.on_pulse_mode_button_clicked)
        mode_pulse_layout.addWidget(mode_pulse_button)
        mode_pulse_group.setLayout(mode_pulse_layout)
        right_layout.addWidget(mode_pulse_group)
        
        # 其他电机模式
        mode_other_group = QGroupBox("其他电机模式")
        mode_other_layout = QFormLayout()
        self.start_mode = QComboBox()
        self.start_mode.addItems(["position", "speed"])
        mode_other_layout.addRow("电机模式", self.start_mode)
        
        self.motor_direction = QComboBox()
        self.motor_direction.addItems(["CW", "CCW"])
        mode_other_layout.addRow("Direction", self.motor_direction)
        
        self.target_position = QLineEdit("0")
        mode_other_layout.addRow("Target Position", self.target_position)
        
        self.target_speed = QLineEdit("100")
        mode_other_layout.addRow("Target Speed", self.target_speed)
        
        self.start_button = QPushButton("Start")
        self.start_button.clicked.connect(self.on_start_button_clicked)
        mode_other_layout.addWidget(self.start_button)
        
        self.stop_button = QPushButton("Stop")
        self.stop_button.clicked.connect(self.on_stop_button_clicked)
        mode_other_layout.addWidget(self.stop_button)
        
        mode_other_group.setLayout(mode_other_layout)
        right_layout.addWidget(mode_other_group)
        
        # 便捷按键
        button_texts = ["--", "-", "+", "++"]
        quick_buttons_layout = QHBoxLayout()
        for text in button_texts:
            button = QPushButton(text)
            button.pressed.connect(lambda t=text: self.on_quickButton_pressed(t))
            button.released.connect(lambda t=text: self.on_quickButton_released(t))
            quick_buttons_layout.addWidget(button)
        right_layout.addLayout(quick_buttons_layout)
        
        main_layout.addLayout(left_layout)
        main_layout.addLayout(right_layout)
        self.setLayout(main_layout)
    
    # 按键: Refresh
    def on_refresh_button_clicked(self):
        # print("Updating serial ports")
        self.serial_port_combo.clear()
        # print(self.serial_motor_control.get_available_ports())
        self.serial_port_combo.addItems(self.serial_motor_control.get_available_ports())
        print("Serial ports refreshed.")
    
    # 按键: Connect
    def on_connect_button_clicked(self):
        selected_port = self.serial_port_combo.currentText()
        if self.serial_motor_control.connected:
            self.serial_motor_control.disconnect()
            self.connect_button.setText("Connect")
            self.motor_status_label.setText("Motor Status: Disconnected")
            print(f"Disconnected from {selected_port}.")
            self.status_textEdit.append(f"Disconnected from {selected_port}.")
        else:
            self.status_textEdit.append(f"Connecting to {selected_port}...")
            if self.serial_motor_control.connect(self.serial_port_combo.currentText()):
                self.connect_button.setText("Disconnect")
                print(f"Connected to {selected_port}.")
                self.status_textEdit.append(f"Successfully Connected!")
            else:
                self.status_textEdit.append(f"Cannot connect to {selected_port}.")
                QMessageBox.warning(self, "Error", "Cannot connect to the serial port")
            
    
    # ----------
    # MCU引脚控制
    # ----------
    def on_motor_index_changed(self, index):
        self.current_motor_index = index
        self.linEdit_pin_dir.setText(str(dirPin[index]))
        self.lineEdit_pin_pul.setText(str(stepPins[index]))
        self.lineEdit_pin_en.setText(str(enablePin[index]))
        pin_config = {
            "DIR": dirPin[index],
            "PUL": stepPins[index],
            "EN": enablePin[index]
        }
        return pin_config
    
    # ----------
    # 脉冲模式
    # ----------
    def on_pulse_number_changed(self, text):
        try:
            self.pulse_number = int(text)
        except ValueError:
            self.pulse_number = 1000
            self.sender().setText("1000")
    
    def on_pulse_period_changed(self, text):
        try:
            self.pulse_period = int(text)
        except ValueError:
            self.pulse_period = 1000
            self.sender().setText("1000")
    
    def on_pulse_mode_button_clicked(self):
        command = f"M{self.current_motor_index}:{self.pulse_number}:{self.pulse_period}"
        self.serial_motor_control.send_data(command)
    
    # ----------
    # 其他电机模式
    # ----------
    def on_start_button_clicked(self):
        # 启动电机
        speed = self.speed_slider.value()
        direction = self.direction_combo.currentText()
        print(f"Starting motor at speed {speed} and direction {direction}.")
        self.motor_status_label.setText("Motor Status: Running")

    def on_stop_button_clicked(self):
        # 停止电机
        self.serial_motor_control.send_data("stop")
        print("Stopping motor.")
        self.motor_status_label.setText("Motor Status: Stopped")

    def on_quickButton_pressed(self, text):
        if text == "--": 
            self.serial_motor_control.continue_move(0, 'quick', motor_number=self.current_motor_index)
        elif text == "-":
            self.serial_motor_control.continue_move(0, 'slow', motor_number=self.current_motor_index)
        elif text == "+":
            self.serial_motor_control.continue_move(1, 'slow', motor_number=self.current_motor_index)
        elif text == "++":
            self.serial_motor_control.continue_move(1, 'quick', motor_number=self.current_motor_index)
    
    def on_quickButton_released(self, text):
        self.serial_motor_control.send_data(f"stop:{self.current_motor_index}")
                      
